package com.qidian.check.util.interceptor;

import com.alibaba.fastjson2.JSON;
import com.qidian.check.util.annotation.CheckParam;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: 小可怎么都睡不够
 * @Description:
 * @Time: 2024-04-17 20:12
 **/

public class CheckParamHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取执行方法的全限定类名
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        Map<String, String[]> resultValMap = request.getParameterMap();

        Parameter[] parameters = method.getParameters();
        Map<String, String> result = new HashMap<>();
        for (Parameter parameter : parameters) {
            CheckParam checkParam = parameter.getAnnotation(CheckParam.class);
            if (checkParam != null) {
                if (checkParam.required()) {
                    if (resultValMap.get(parameter.getName()) ==null || "".equals(resultValMap.get(parameter.getName())[0])) {
                        result.put("code", "500");
                        if(parameter.getType() != checkParam.type()){
                            result.put("msg", "参数传递有误，应该是" + checkParam.type().getName() + "但是你传入的是" + parameter.getType().getName());
                        }else{
                            result.put("msg", "参数传递有误，应该是" + checkParam.type().getName() + "但是你传入的是 null");
                        }
                        response.setContentType("application/json;charset=utf-8");
                        response.setStatus(500);
                        response.getWriter().write(JSON.toJSONString(result));
                        return false;
                    }
                    if (checkParam.allowedValues().length > 0) {
                        if (Arrays.stream(checkParam.allowedValues()).noneMatch(value -> value.equals(resultValMap.get(parameter.getName())[0]))) {
                            //如果这个参数不在指定的值中
                            result.put("code", "500");
                            response.setContentType("application/json;charset=utf-8");
                            response.setStatus(500);
                            result.put("msg", "参数传递有误，应该是在 " + Arrays.asList(checkParam.allowedValues()) + " 之中，但是你传入的是 " + Arrays.toString(resultValMap.get(parameter.getName())));
                            response.getWriter().write(JSON.toJSONString(result));

                            return false;
                        }
                    }
                    if (!checkParam.range()) return true;
                    if (checkParam.min() != Integer.MIN_VALUE) {
                        if (Integer.parseInt(resultValMap.get(parameter.getName())[0]) < checkParam.min()) {
                            result.put("code", "500");
                            response.setContentType("application/json;charset=utf-8");
                            response.setStatus(500);
                            result.put("msg", "参数传递有误，应该是大于等于 " + checkParam.min() + " 的整数，但是你传入的是 " + Arrays.toString(resultValMap.get(parameter.getName())));
                            response.getWriter().write(JSON.toJSONString(result));

                            return false;
                        }
                    }
                    if (checkParam.max() != Integer.MAX_VALUE) {
                        if (Integer.parseInt(resultValMap.get(parameter.getName())[0]) > checkParam.max()) {
                            result.put("code", "500");
                            response.setContentType("application/json;charset=utf-8");
                            response.setStatus(500);
                            result.put("msg", "参数传递有误，应该是小于等于 " + checkParam.max() + " 的整数，但是你传入的是 " + Arrays.toString(resultValMap.get(parameter.getName())));
                            response.getWriter().write(JSON.toJSONString(result));

                            return false;
                        }
                    }

                }
            }
        }
        System.out.println("res");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

}
